home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / lfs / lfsStableMem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  18.3 KB  |  633 lines

  1. /* 
  2.  * LfsStableMem.c --
  3.  *
  4.  *    Generic routines for supporting an in memory data structure that
  5.  *    is written to a LFS log at each checkpoint.  The blocks of the
  6.  *    data structures are kept as file in the file cache.
  7.  *
  8.  * Copyright 1989 Regents of the University of California
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/lfs/lfsStableMem.c,v 1.12 92/06/01 15:07:25 kupfer Exp $ SPRITE (Berkeley)";
  20. #endif /* not lint */
  21.  
  22. #include <lfsInt.h>
  23. #include <lfsSeg.h>
  24. #include <lfsStableMemInt.h>
  25. #include <stdlib.h>
  26. #include <fsdm.h>
  27.  
  28. static Boolean AddBlockToSegment _ARGS_((LfsStableMem *smemPtr, 
  29.             Address address, int blockNum, ClientData clientData,
  30.             LfsSeg *segPtr));
  31. static Boolean BlockMatch _ARGS_((Fscache_Block *blockPtr, 
  32.             ClientData clientData));
  33.  
  34.  
  35.  
  36. /*
  37.  *----------------------------------------------------------------------
  38.  *
  39.  * LfsStableMemLoad --
  40.  *
  41.  *     Allocate and load a LFS stable memory resident data structure.
  42.  *
  43.  * Results:
  44.  *    SUCCESS if load succeed ok.
  45.  *
  46.  * Side effects:
  47.  *    Many
  48.  *
  49.  *----------------------------------------------------------------------
  50.  */
  51.  
  52. ReturnStatus
  53. LfsStableMemLoad(lfsPtr, smemParamsPtr, checkPointSize, checkPointPtr, smemPtr)
  54.     Lfs *lfsPtr;       /* File system of metadata. */
  55.     LfsStableMemParams  *smemParamsPtr; /* Parameters for this memory. */
  56.     int  checkPointSize;   /* Size of checkpoint data. */
  57.     char *checkPointPtr;   /* Data from last checkpoint before shutdown. */
  58.     LfsStableMem    *smemPtr; /* In memeory index data structures. */
  59. {
  60.     int    blockNum, bufferSize; 
  61.     LfsStableMemCheckPoint *cpPtr;
  62.     Fscache_Attributes       attr;
  63.     static    int    nextMinorNumber = -1;
  64.  
  65.     cpPtr = (LfsStableMemCheckPoint *)     checkPointPtr;
  66.     /*
  67.      * Do some bounds checking on the checkpoint buffer.
  68.      */
  69.     if ((checkPointSize < sizeof(LfsStableMemCheckPoint)) ||
  70.         (checkPointSize < (cpPtr->numBlocks * sizeof(int) + 
  71.                 sizeof(LfsStableMemCheckPoint))))  {
  72.     return FAILURE;
  73.     }
  74.     /*
  75.      * Fill in the LfsStableMem data structures.
  76.      *
  77.      */
  78.     smemPtr->lfsPtr = lfsPtr;
  79.     /*
  80.      * Initialize the file handle used for storing blocks in the
  81.      * file cache.
  82.      */
  83.  
  84.     bzero((Address)&smemPtr->dataHandle, sizeof(smemPtr->dataHandle));
  85.     smemPtr->dataHandle.hdr.fileID.serverID = rpc_SpriteID;
  86.     smemPtr->dataHandle.hdr.fileID.major = lfsPtr->domainPtr->domainNumber;
  87.     smemPtr->dataHandle.hdr.fileID.minor = nextMinorNumber--;
  88.     smemPtr->dataHandle.hdr.fileID.type = FSIO_LCL_FILE_STREAM;
  89.     smemPtr->dataHandle.hdr.name = "LfsStableMemFile";
  90.     smemPtr->dataHandle.descPtr = (Fsdm_FileDescriptor *)NIL;
  91.  
  92.     bzero((Address)&attr, sizeof(attr));
  93.     attr.lastByte = smemParamsPtr->blockSize * smemParamsPtr->maxNumBlocks;
  94.     Fscache_FileInfoInit(&smemPtr->dataHandle.cacheInfo,
  95.             (Fs_HandleHeader *) &smemPtr->dataHandle,
  96.             0, TRUE, &attr, lfsPtr->domainPtr->backendPtr);
  97.  
  98.     /*
  99.      * Allocate and copy the index for the metadata.
  100.      */
  101.     bufferSize = smemParamsPtr->maxNumBlocks * sizeof(int);
  102.     smemPtr->blockIndexPtr = (LfsDiskAddr *) malloc(bufferSize);
  103.     bcopy(checkPointPtr + sizeof(LfsStableMemCheckPoint), 
  104.          (char *) smemPtr->blockIndexPtr, 
  105.          cpPtr->numBlocks * sizeof(LfsDiskAddr));
  106.     for (blockNum = cpPtr->numBlocks; blockNum < smemParamsPtr->maxNumBlocks;
  107.             blockNum++) {
  108.     LfsSetNilDiskAddr(&smemPtr->blockIndexPtr[blockNum]);
  109.     }
  110.  
  111.     smemPtr->numCacheBlocksOut = 0;
  112.     /*
  113.      * Fillin the rest of the LfsStableMem data structure with a copy
  114.      * of the checkPoint and Params data.
  115.      */
  116.  
  117.     smemPtr->checkPoint = *cpPtr;
  118.     smemPtr->params = *smemParamsPtr;
  119.  
  120.     return SUCCESS;
  121. }
  122.  
  123.  
  124. /*
  125.  *----------------------------------------------------------------------
  126.  *
  127.  * LfsStableMemLoad --
  128.  *
  129.  *     Allocate and load a LFS stable memory resident data structure.
  130.  *
  131.  * Results:
  132.  *    SUCCESS if load succeed ok.
  133.  *
  134.  * Side effects:
  135.  *    Many
  136.  *
  137.  *----------------------------------------------------------------------
  138.  */
  139.  
  140. ReturnStatus
  141. LfsStableMemDestory(lfsPtr, smemPtr)
  142.     Lfs *lfsPtr;       /* File system of metadata. */
  143.     LfsStableMem    *smemPtr; /* In memeory index data structures. */
  144. {
  145.     Fscache_FileInvalidate(&smemPtr->dataHandle.cacheInfo, 0, 
  146.             FSCACHE_LAST_BLOCK);
  147.  
  148.     free((char *) smemPtr->blockIndexPtr);
  149.  
  150.     return SUCCESS;
  151. }
  152.  
  153.  
  154. /*
  155.  *----------------------------------------------------------------------
  156.  *
  157.  * LfsStableMemClean --
  158.  *
  159.  *    Routine to handle cleaning pieces containing data for this module.
  160.  *
  161.  * Results:
  162.  *    TRUE if more data needs to be written, FALSE if this module is
  163.  *    happy for the time being.
  164.  *
  165.  * Side effects:
  166.  *    Many
  167.  *
  168.  *----------------------------------------------------------------------
  169.  */
  170.  
  171. Boolean
  172. LfsStableMemClean(segPtr, sizePtr, numCacheBlocksPtr, clientDataPtr, smemPtr)
  173.     LfsSeg *segPtr;    /* Segment containing data to clean. */
  174.     int *sizePtr;
  175.     int *numCacheBlocksPtr;
  176.     ClientData *clientDataPtr;
  177.     LfsStableMem *smemPtr;    /* Index pointer. */
  178. {
  179.     char *summaryPtr;
  180.     int     *blockPtr;
  181.     int     numBlocks, block, blockOffset;
  182.     LfsDiskAddr blockAddress;
  183.     ReturnStatus    status;
  184.     LfsStableMemEntry entry;
  185.  
  186.     summaryPtr = LfsSegGetSummaryPtr(segPtr);
  187.     numBlocks = LfsSegSummaryBytesLeft(segPtr) / sizeof(int);
  188.     blockPtr = (int *) summaryPtr;
  189.     blockAddress = LfsSegDiskAddress(segPtr, LfsSegGetBufferPtr(segPtr));
  190.     blockOffset = 0;
  191.     /*
  192.      * For each block that hasn't moved already, fetch and release the
  193.      * block marking it as dirty.
  194.      */
  195.     for (block = 0; block < numBlocks; block++) { 
  196.     LfsDiskAddr newDiskAddr;
  197.      blockOffset += LfsBytesToBlocks(segPtr->lfsPtr, 
  198.                     smemPtr->params.blockSize);
  199.     LfsDiskAddrPlusOffset(blockAddress, -blockOffset, &newDiskAddr);
  200.     if (LfsSameDiskAddr(smemPtr->blockIndexPtr[blockPtr[block]], 
  201.             newDiskAddr)) {
  202.         int entryNumber = blockPtr[block] * smemPtr->params.entriesPerBlock;
  203.         status = LfsStableMemFetch(smemPtr, entryNumber, 0, &entry);
  204.         if (status != SUCCESS) {
  205.         LfsError(segPtr->lfsPtr, status,"Can't clean metadata block\n");
  206.         }
  207.         LfsStableMemRelease(smemPtr, &entry, TRUE);
  208.         (*sizePtr) += smemPtr->params.blockSize;
  209.      }
  210.     }
  211.     return FALSE;
  212. }
  213.  
  214.  
  215. /*
  216.  *----------------------------------------------------------------------
  217.  *
  218.  * LfsStableMemCheckpoint --
  219.  *
  220.  *    Routine to handle checkpointing of data for this module.
  221.  *
  222.  * Results:
  223.  *    TRUE if more data needs to be written, FALSE if this module is
  224.  *    checkpointed.
  225.  *
  226.  * Side effects:
  227.  *    Many
  228.  *
  229.  *----------------------------------------------------------------------
  230.  */
  231.  
  232. Boolean
  233. LfsStableMemCheckpoint(segPtr, checkPointPtr, flags, checkPointSizePtr,
  234.             clientDataPtr, smemPtr)
  235.     LfsSeg *segPtr;        /* Segment containing data for checkpoint. */
  236.     char   *checkPointPtr;      /* Buffer to write checkpoint data. */
  237.     int       flags;        /* Flags. */
  238.     int       *checkPointSizePtr;  /* Bytes added to the checkpoint area.*/
  239.     ClientData *clientDataPtr;
  240.     LfsStableMem *smemPtr;    /* Stable memory description. */
  241. {
  242.     Boolean    full = FALSE;
  243.  
  244.     full = LfsStableMemLayout(segPtr, LFS_CHECKPOINT_LAYOUT,
  245.             clientDataPtr, smemPtr);
  246.     /*
  247.      * If we didn't fill the segment, copy the index to the checkpoint buffer.
  248.      */
  249.     if (!full) {
  250.     *(LfsStableMemCheckPoint *) checkPointPtr = smemPtr->checkPoint;
  251.     bcopy((char *) smemPtr->blockIndexPtr, 
  252.         checkPointPtr + sizeof(LfsStableMemCheckPoint), 
  253.         sizeof(LfsDiskAddr) * smemPtr->checkPoint.numBlocks);
  254.     *checkPointSizePtr = sizeof(int) * smemPtr->checkPoint.numBlocks + 
  255.                 sizeof(LfsStableMemCheckPoint);
  256.     LFS_STATS_INC(segPtr->lfsPtr->stats.checkpoint.samples);
  257.     switch (smemPtr->params.memType) {
  258.         case LFS_DESC_MAP_MOD: {
  259.         LFS_STATS_ADD(segPtr->lfsPtr->stats.desc.residentCount,
  260.             smemPtr->dataHandle.cacheInfo.blocksInCache);
  261.         break;
  262.         }
  263.         case LFS_SEG_USAGE_MOD: {
  264.         LFS_STATS_ADD(segPtr->lfsPtr->stats.segusage.residentCount,
  265.             smemPtr->dataHandle.cacheInfo.blocksInCache);
  266.         break;
  267.         }
  268.     }
  269.     }
  270.     return full;
  271. }
  272.  
  273.  
  274. /*
  275.  *----------------------------------------------------------------------
  276.  *
  277.  * LfsStableMemLayout --
  278.  *
  279.  *    Routine to handle writing of data for this module.
  280.  *
  281.  * Results:
  282.  *    TRUE if more data needs to be written, FALSE if this module is
  283.  *    checkpointed.
  284.  *
  285.  * Side effects:
  286.  *    Many
  287.  *
  288.  *----------------------------------------------------------------------
  289.  */
  290.  
  291. Boolean
  292. LfsStableMemLayout(segPtr, flags, clientDataPtr, smemPtr)
  293.     LfsSeg *segPtr;        /* Segment to place data blocks in. */
  294.     int        flags;        /* Layout flags. */
  295.     ClientData    *clientDataPtr;
  296.     LfsStableMem *smemPtr;    /* Stable memory description. */
  297. {
  298.     Boolean    full = FALSE;
  299.     Fscache_FileInfo    *cacheInfoPtr;
  300.     Fscache_Block    *blockPtr;
  301.     int            lastDirtyBlock;
  302.     Boolean        fsyncOnly;
  303.  
  304.  
  305.     /*
  306.      * Find and layout all the dirty metadata blocks. 
  307.      */
  308.     if (*clientDataPtr == (ClientData) NIL) { 
  309.     fsyncOnly = ((flags  & LFS_CHECKPOINT_LAYOUT) == 0);
  310.     cacheInfoPtr = Fscache_GetDirtyFile(
  311.                 segPtr->lfsPtr->domainPtr->backendPtr,
  312.                 fsyncOnly, LfsFileMatch, 
  313.             (ClientData) (smemPtr->dataHandle.hdr.fileID.minor));
  314.     if (cacheInfoPtr == (Fscache_FileInfo *) NIL) {
  315.         return FALSE;
  316.     }
  317.     *clientDataPtr = (ClientData) cacheInfoPtr;
  318.     } else {
  319.     cacheInfoPtr = (Fscache_FileInfo *) *clientDataPtr;
  320.     }
  321.  
  322.     while(!full) { 
  323.     blockPtr = Fscache_GetDirtyBlock(cacheInfoPtr, BlockMatch,
  324.                 (ClientData) 0, &lastDirtyBlock);
  325.     if (blockPtr == (Fscache_Block *) NIL) {
  326.         break;
  327.     }
  328.     full = AddBlockToSegment(smemPtr, blockPtr->blockAddr, 
  329.             blockPtr->blockNum, (ClientData) blockPtr, segPtr);
  330.     if (full) {
  331.         Fscache_ReturnDirtyBlock(blockPtr, GEN_EINTR);
  332.     } else {
  333.         smemPtr->numCacheBlocksOut++;
  334.     }
  335.  
  336.     }
  337.     if (!full && (smemPtr->numCacheBlocksOut == 0)) {
  338.     Fscache_ReturnDirtyFile(cacheInfoPtr, FALSE);
  339.     }
  340.     return full;
  341. }
  342.  
  343.  
  344. /*
  345.  *----------------------------------------------------------------------
  346.  *
  347.  * LfsStableMemWriteDone --
  348.  *
  349.  *    Routine to inform this module that a write has finished.
  350.  *
  351.  * Results:
  352.  *    None.
  353.  *
  354.  * Side effects:
  355.  *    Many
  356.  *
  357.  *----------------------------------------------------------------------
  358.  */
  359.  
  360. void
  361. LfsStableMemWriteDone(segPtr, flags, clientDataPtr, smemPtr)
  362.     LfsSeg *segPtr;    /* Segment whose write finishes. */
  363.     int        flags;    /* Write done flags. */
  364.     ClientData *clientDataPtr;
  365.     LfsStableMem *smemPtr;    /* Index description. */
  366. {
  367.     LfsSegElement *bufferLimitPtr, *bufferPtr = LfsSegGetBufferPtr(segPtr);
  368.     Fscache_Block *blockPtr;
  369.  
  370.     blockPtr = (Fscache_Block *) NIL;
  371.     bufferLimitPtr = bufferPtr + LfsSegSummaryBytesLeft(segPtr) / sizeof(int);
  372.     while (bufferPtr < bufferLimitPtr) {
  373.     blockPtr = (Fscache_Block *) bufferPtr->clientData;
  374.     Fscache_ReturnDirtyBlock(blockPtr, SUCCESS);
  375.     bufferPtr++;
  376.     smemPtr->numCacheBlocksOut--;
  377.     }
  378.     if (smemPtr->numCacheBlocksOut == 0) {
  379.     Fscache_ReturnDirtyFile((Fscache_FileInfo *)(*clientDataPtr), FALSE);
  380.     }
  381.     LfsSegSetBufferPtr(segPtr, bufferPtr);
  382. }
  383. /*
  384.  *----------------------------------------------------------------------
  385.  *
  386.  * LfsStableMemFetch --
  387.  *
  388.  *    Routine to fetch a stable memory entry and optionally release
  389.  *    a previously fetched entry.   This routine fetches the data block
  390.  *    from the file cache reading it in if it is not present.
  391.  *
  392.  * Results:
  393.  *    SUCCESS if entry is fetch. GEN_INVALID_ARG if entryNumber is not
  394.  *    vaild. Other ReturnStatus if disk read fails.
  395.  *
  396.  * Side effects:
  397.  *    Cache block fetched. Possibly disk I/O performed.
  398.  *
  399.  *----------------------------------------------------------------------
  400.  */
  401.  
  402. ReturnStatus
  403. LfsStableMemFetch(smemPtr, entryNumber, flags, entryPtr)
  404.     LfsStableMem *smemPtr;    /* Index description. */
  405.     int         entryNumber;    /* Entry number wanted. */
  406.     int        flags;    /* LFS_STABLE_MEM_MAY_DIRTY | LFS_STABLE_MEM_REL_ENTRY*/
  407.     LfsStableMemEntry *entryPtr; /* IN/OUT: Stable memory entry returned. */
  408. {
  409.     Fscache_Block        *blockPtr;
  410.     Boolean            found;
  411.     int         blockNum, offset;
  412.     ReturnStatus    status = SUCCESS;
  413.     Boolean        releaseEntry;
  414.     LfsStableMemBlockHdr *hdrPtr;
  415.  
  416.     releaseEntry = ((flags & LFS_STABLE_MEM_REL_ENTRY) != 0);
  417.     if ((entryNumber < 0) || (entryNumber >= smemPtr->params.maxNumEntries)) {
  418.     if (releaseEntry) {
  419.         LfsStableMemRelease(smemPtr, entryPtr, entryPtr->modified);
  420.     }
  421.     return GEN_INVALID_ARG;
  422.     }
  423.     blockNum = entryNumber / smemPtr->params.entriesPerBlock;
  424.     offset = (entryNumber % smemPtr->params.entriesPerBlock) * 
  425.         smemPtr->params.entrySize + sizeof(LfsStableMemBlockHdr);
  426.     blockPtr = (Fscache_Block *) NIL;
  427.     if (releaseEntry) {
  428.     if (entryPtr->blockNum == blockNum) { 
  429.         blockPtr = (Fscache_Block *) entryPtr->clientData;
  430.     } else {
  431.         LfsStableMemRelease(smemPtr, entryPtr, entryPtr->modified);
  432.     }
  433.     }
  434.     if (blockPtr == (Fscache_Block *) NIL) {
  435.     Boolean dirtied;
  436.     int    cacheFlags;
  437.     /*
  438.      * Fetch the block from the cache reading it in if needed.
  439.      */
  440.     cacheFlags = FSCACHE_DESC_BLOCK|FSCACHE_CANT_BLOCK;
  441.     if (flags & LFS_STABLE_MEM_MAY_DIRTY) {
  442.         cacheFlags |= FSCACHE_IO_IN_PROGRESS;
  443.     }
  444.     switch (smemPtr->params.memType) {
  445.         case LFS_DESC_MAP_MOD: {
  446.         LFS_STATS_INC(smemPtr->lfsPtr->stats.desc.descMapBlockAccess);
  447.         break;
  448.         }
  449.         case LFS_SEG_USAGE_MOD: {
  450.         LFS_STATS_INC(smemPtr->lfsPtr->stats.segusage.segUsageBlockAccess);
  451.         break;
  452.         }
  453.     }
  454.     Fscache_FetchBlock(&smemPtr->dataHandle.cacheInfo, blockNum, 
  455.                  cacheFlags, &blockPtr, &found);
  456.     dirtied = FALSE;
  457.     if (!found && (blockPtr != (Fscache_Block *) NIL) ) {
  458.         if (LfsIsNilDiskAddr(smemPtr->blockIndexPtr[blockNum])) {
  459.         bzero(blockPtr->blockAddr, smemPtr->params.blockSize);
  460.         hdrPtr = (LfsStableMemBlockHdr *) blockPtr->blockAddr;
  461.         hdrPtr->magic = LFS_STABLE_MEM_BLOCK_MAGIC;
  462.         hdrPtr->memType = smemPtr->params.memType;
  463.         hdrPtr->blockNum = blockNum;
  464.         dirtied = TRUE;
  465.          } else {
  466.         switch (smemPtr->params.memType) {
  467.             case LFS_DESC_MAP_MOD: {
  468.             LFS_STATS_INC(smemPtr->lfsPtr->stats.desc.descMapBlockMiss);
  469.             break;
  470.             }
  471.             case LFS_SEG_USAGE_MOD: {
  472.             LFS_STATS_INC(smemPtr->lfsPtr->stats.segusage.segUsageBlockMiss);
  473.             break;
  474.             }
  475.         }
  476.         status = LfsReadBytes(smemPtr->lfsPtr, 
  477.                      smemPtr->blockIndexPtr[blockNum],
  478.                      smemPtr->params.blockSize, 
  479.                      blockPtr->blockAddr);
  480. #ifdef ERROR_CHECK
  481.          if (smemPtr->params.memType != LFS_SEG_USAGE_MOD) {
  482.              LfsCheckRead(smemPtr->lfsPtr, 
  483.                 smemPtr->blockIndexPtr[blockNum], 
  484.                 smemPtr->params.blockSize);
  485.           }
  486. #endif
  487.          }
  488.  
  489.          if (status != SUCCESS) {
  490.         Fscache_UnlockBlock(blockPtr, (time_t)0, -1, 0,
  491.                     FSCACHE_DELETE_BLOCK);
  492.          }
  493.     }
  494.     entryPtr->modified = dirtied;
  495.     }
  496.     if (blockPtr != (Fscache_Block *) NIL) {
  497. #ifdef ERROR_CHECK
  498.     hdrPtr = (LfsStableMemBlockHdr *) blockPtr->blockAddr;
  499.     if ((hdrPtr->magic != LFS_STABLE_MEM_BLOCK_MAGIC) || 
  500.         (hdrPtr->memType != smemPtr->params.memType) ||
  501.         (hdrPtr->blockNum != blockNum)) {
  502.         LfsError(smemPtr->lfsPtr, FAILURE, "Bad LfsStableMemBlockHdr\n");
  503.     }
  504. #endif /* ERROR_CHECK */
  505.     entryPtr->addr = blockPtr->blockAddr + offset;
  506.     entryPtr->blockNum = blockNum;
  507.     entryPtr->clientData = (ClientData) blockPtr;
  508.     } else {
  509.     status = FS_WOULD_BLOCK;
  510.     }
  511.     return status;
  512. }
  513.  
  514. /*
  515.  *----------------------------------------------------------------------
  516.  *
  517.  * LfsStableMemRelease --
  518.  *
  519.  *    Routine to release a previous fetched stable memory ebtrt,
  520.  *
  521.  * Results:
  522.  *    None.
  523.  *
  524.  * Side effects:
  525.  *    Many
  526.  *
  527.  *----------------------------------------------------------------------
  528.  */
  529.  
  530. void
  531. LfsStableMemRelease(smemPtr, entryPtr, modified)
  532.     LfsStableMem *smemPtr;    /* Index description. */
  533.     LfsStableMemEntry *entryPtr; /*  Stable memory entry to return. */
  534.     Boolean    modified;    /* TRUE if block was modified. */
  535. {
  536.     Fscache_Block    *blockPtr;
  537.     time_t        timeDirtied;
  538.     int            blockNum;
  539.  
  540.     blockPtr = (Fscache_Block *) entryPtr->clientData;
  541.     blockNum = blockPtr->blockNum;
  542.     modified = modified || entryPtr->modified;
  543.     timeDirtied = modified ? -1 : 0;
  544.     Fscache_UnlockBlock(blockPtr, timeDirtied, blockNum,  
  545.             smemPtr->params.blockSize, 0);
  546.     entryPtr->addr = (Address)NIL;
  547.     if (modified && !LfsIsNilDiskAddr(smemPtr->blockIndexPtr[blockNum])) {
  548.         /*
  549.      * If the block was modified free the old address up.
  550.      */
  551.     LfsSegUsageFreeBlocks(smemPtr->lfsPtr, 
  552.         (int)(smemPtr->params.blockSize), 1, 
  553.         (LfsDiskAddr *) smemPtr->blockIndexPtr + blockNum);
  554.  
  555.     }
  556.     return;
  557. }
  558.  
  559. /*
  560.  *----------------------------------------------------------------------
  561.  *
  562.  * AddBlockToSegment --
  563.  *
  564.  *    Add a metadata block to the specified segment.
  565.  *
  566.  * Results:
  567.  *    TRUE if segment is full so we couldn't add block.
  568.  *
  569.  * Side effects:
  570.  *    None.
  571.  *
  572.  *----------------------------------------------------------------------
  573.  */
  574.  
  575.  
  576. static Boolean
  577. AddBlockToSegment(smemPtr, address, blockNum, clientData, segPtr)
  578.     LfsStableMem *smemPtr;    /* Index of block. */
  579.     Address      address;    /* Address of block. */
  580.     int        blockNum;    /* Block number. */
  581.     ClientData    clientData;    /* Client data for entry. */
  582.     LfsSeg *segPtr;        /* Segment to place data blocks in. */
  583. {
  584.     int    fsBlocks;
  585.     char *summaryPtr;
  586.     LfsSegElement *bufferPtr;
  587.  
  588.     fsBlocks = LfsBytesToBlocks(segPtr->lfsPtr, smemPtr->params.blockSize);
  589.     summaryPtr = LfsSegGrowSummary(segPtr, fsBlocks, sizeof(int));
  590.     if (summaryPtr == (char *)NIL) {
  591.     return TRUE;
  592.     }
  593.     bufferPtr = LfsSegAddDataBuffer(segPtr, fsBlocks, address, clientData);
  594.     *(int *)summaryPtr = blockNum;
  595.     LfsSegSetSummaryPtr(segPtr,summaryPtr + sizeof(int));
  596. #ifdef ERROR_CHECK
  597.     if (!LfsIsNilDiskAddr(smemPtr->blockIndexPtr[blockNum])) {
  598.     panic("StableMem:AddBlockToSegment disk address not NIL\n");
  599.     }
  600. #endif
  601.     smemPtr->blockIndexPtr[blockNum] = LfsSegDiskAddress(segPtr, bufferPtr);
  602.     segPtr->activeBytes += smemPtr->params.blockSize;
  603.     if (blockNum >= smemPtr->checkPoint.numBlocks) {
  604.     smemPtr->checkPoint.numBlocks = blockNum + 1;
  605.     }
  606.     return FALSE;
  607. }
  608.  
  609.  
  610. /*
  611.  * ----------------------------------------------------------------------------
  612.  *
  613.  * BlockMatch --
  614.  *
  615.  *     Cache backend block type match.  
  616.  *
  617.  * Results:
  618.  *    TRUE.
  619.  *
  620.  * Side effects:
  621.  *
  622.  * ----------------------------------------------------------------------------
  623.  */
  624. /*ARGSUSED*/
  625. static Boolean
  626. BlockMatch(blockPtr, clientData)
  627.     Fscache_Block *blockPtr;
  628.     ClientData       clientData;
  629. {
  630.     return TRUE;
  631. }
  632.  
  633.